package com.zero.zloader
{
	import com.zero.zevent.LoaderEvent;
	
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.HTTPStatusEvent;
	import flash.events.IEventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.net.URLLoader;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLRequest;
	import flash.net.URLRequestMethod;
	import flash.net.URLVariables;
	import flash.utils.ByteArray;
		
	public class DataLoader extends EventDispatcher
	{
		public var loadCompleteMessage		:String;
		public var loadErrorMessage		:String;
		public var loadProgressMessage		:String;
		
		protected var _url					:String;
		protected var _args				:URLVariables;
		protected var _request				:URLRequest;
		protected var _requestMethod		:String;
		protected var _progress			:Number=0;
		protected var _loader				:URLLoader;
		protected var _isComplete			:Boolean;
		protected var _isSuccess			:Boolean;
		protected var _isLoading			:Boolean;
		
		private var _currentLoadPath		:String;
		private var _currentTryTime		:int = 0;
		private var _bytesLoaded 			:int;
		private var _bytesTotal 			:int;


		
		public function DataLoader($url:String, $args:URLVariables=null, $requestMethod:String=URLRequestMethod.GET, $target:IEventDispatcher=null)
		{
			super($target);
			_url 			= $url;
			_args 			= $args;
			_requestMethod 	= $requestMethod;
			_loader 		= new URLLoader();
			addEvent();
		}
		
		public function get isSuccess():Boolean
		{
			return _isSuccess;
		}
		
		public function get isComplete():Boolean
		{
			return _isComplete;	
		}
		
		public function get isLoading():Boolean
		{
			return _isLoading;
		}
		
		public function get content():*
		{
			return _loader.data;
		}
		
		protected function addEvent():void
		{
			_loader.addEventListener(Event.COMPLETE,__onDataLoadComplete);
			_loader.addEventListener(ProgressEvent.PROGRESS,__onProgress);
			_loader.addEventListener(HTTPStatusEvent.HTTP_STATUS,__onStatus);
			_loader.addEventListener(IOErrorEvent.IO_ERROR,__onIOError);
		}
		
		protected function removeEvent():void
		{
			_loader.removeEventListener(Event.COMPLETE,__onDataLoadComplete);
			_loader.removeEventListener(ProgressEvent.PROGRESS,__onProgress);
			_loader.removeEventListener(HTTPStatusEvent.HTTP_STATUS,__onStatus);
			_loader.removeEventListener(IOErrorEvent.IO_ERROR,__onIOError);
		}
		
		public function loadFromExternal(path:String):void
		{
			startLoad(path);
		}
		
		public function loadFromBytes(data:ByteArray):void
		{
			
		}
		
		public function loadFromWeb():void
		{
			startLoad(_url);
		}
		
		protected function __onDataLoadComplete(event:Event):void
		{
//			BackResourceLoader.instance.removeResource(url);
			removeEvent();
			try{
				_loader.close();
			}
			catch(err :Error){}
			fireCompleteEvent();
		}
		
		protected function fireCompleteEvent():void
		{
			_progress = 1;
			dispatchEvent(new LoaderEvent(LoaderEvent.PROGRESS,this));
			_isSuccess = true;
			_isComplete = true;
			_isLoading = false;
			dispatchEvent(new LoaderEvent(LoaderEvent.COMPLETE,this));
		}
		
		protected function __onProgress(event:ProgressEvent):void
		{
			_progress = event.bytesLoaded/event.bytesTotal;
			_bytesTotal = event.bytesTotal;
			_bytesLoaded = event.bytesLoaded;
			if(loadProgressMessage)loadProgressMessage = loadProgressMessage.replace("{progress}",String(Math.round(_progress*100)));
			dispatchEvent(new LoaderEvent(LoaderEvent.PROGRESS,this));
		}
		
		protected function __onStatus(event:HTTPStatusEvent):void
		{
			if(event.status > 399)
			{
				onLoadError();
			}
		}
		
		protected function __onIOError(event:IOErrorEvent):void
		{
			onLoadError();
		}
		
		protected function onLoadError():void
		{
			dispatchEvent(new LoaderEvent(LoaderEvent.LOAD_ERROR,this));
			dispatchEvent(new LoaderEvent(LoaderEvent.COMPLETE,this));
		}
		
		protected function startLoad(path:String):void
		{
			if(_isLoading || !_loader)return;
			_currentLoadPath = path;
			_loader.dataFormat = getLoadDataFormat();
			_request = new URLRequest(path);
			_request.method = _requestMethod;
			_request.data = _args;
			_isLoading = true;
			_loader.load(_request);
		}
		
		protected function getLoadDataFormat():String
		{
			return URLLoaderDataFormat.BINARY;
		}
	}
}